home *** CD-ROM | disk | FTP | other *** search
- #include "3DDEF.H"
- #include "GLOBAL.H"
- #include "FORWARD.H"
- #include "XCODE.H"
-
- /* 行管理 */
-
- /* カレントウインドウの最上行を得る */
- UNIT *
- line_my_top()
- {
- register UNIT *p;
-
- p = SCREEN[CWY0];
- if ((int)p & (int)0xffffff00) {
- return(p);
- }
- return(SCREEN[CWY0]);
- }
-
- /* カレントウインドウの n 行目を得る */
- UNIT *
- line_my_screen(int n)
- {
- return(SCREEN[CWY0 + n]);
- }
-
- /* w 番ウインドウの n 行目を得る */
- UNIT *
- line_x_screen(int w,int n)
- {
- return(SCREEN[WDATA[w].WY0 + n]);
- }
-
- /* up の begin_byte から、tb バイトだけたどる */
- /* 新しい行へのポインタを返す */
- /* new_byte_count にその行の何バイト目なのかを返す */
- /* movel != NIL なら、*movel に、実際に移動した行数(+-)を返す */
- UNIT *
- line_trace_byte(UNIT *up, int begin_byte, int tb, int *new_byte_count, int *movel)
- {
- register UNIT *wp;
- register int len,counter = 0;
-
- tb += begin_byte;
- wp = up;
-
- line_seigyou();
- if (tb >= 0) { /* 後ろへトレース */
- while(1) {
- len = (wp->LENGTH);
- if (len >= tb) {
- *new_byte_count = tb;
- break;
- }
- tb -= len;
- #if 0
- if (!(wp->ATO)) {
- wp->ATO = TAIL;
- *new_byte_count = wp->LENGTH; /* 最後の行の右端 */
- break;
- }
- #endif
- if ((wp = wp->ATO) == TAIL) {
- wp = TAIL->MAE;
- *new_byte_count = wp->LENGTH; /* 最後の行の右端 */
- break;
- }
- counter++;
- }
- } else { /* 前へトレース */
- tb = -tb;
- while(1) {
- len = wp->LENGTH;
- if (len >= tb) {
- *new_byte_count = len - tb;
- break;
- }
- tb -= len;
- if ((wp = wp->MAE) == HEAD) {
- wp = HEAD->ATO;
- *new_byte_count = 0; /* 最初の行の左端 */
- break;
- }
- counter--;
- }
- }
- if (movel) {
- *movel = counter;
- }
- return(wp);
- }
-
- /* up から tl 行たどる */
- /* 頭もしくは尾に達したら 頭行もしくは尾行を返す */
- /* movel != NIL なら、*movel に、実際に移動した行数(+-)を返す */
- UNIT *
- line_trace(UNIT *up, int tl, int *movel)
- {
- register UNIT *wp;
- register int i,counter=0;
-
- wp = up;
-
- if (tl) { /* tl が0でないなら */
- if (tl > 0) {
- for(i=0;i<tl;i++,counter++) {
- if (wp == NULL) {
- break;
- }
- if ((wp = wp->ATO) == TAIL) {
- wp = TAIL->MAE; /* 戻る */
- break;
- }
- if (wp->ATO == NULL) {
- wp = wp->MAE;
- counter--;
- break;
- }
- }
- } else {
- tl = -tl;
- for(i=0;i<tl;i++,counter--) {
- if (wp == NULL) {
- break;
- }
- if ((wp = wp->MAE) == HEAD) {
- wp = HEAD->ATO; /* 戻る */
- break;
- }
- if (wp->MAE == NULL) {
- wp = wp->ATO;
- counter--;
- break;
- }
- }
- }
- }
- if (movel) {
- *movel = counter;
- }
- return(wp);
- }
-
- /* up の指す行の行頭に s1+s2 を挿入し、次々に送って行く。最後まで勝負する */
- /* エコーする */
- void
- line_arrange(UNIT *up,STR s1,STR s2)
- {
- UBYTE seed[strlen(s1)+strlen(s2)+VERY_LONG_LINE+1];
- UBYTE w0[VERY_LONG_LINE],retw[VERY_LONG_LINE];
- UNIT *wp,*np;
- register int restl;
- int flag;
-
- strcpy(seed,s1);
- strcat(seed,s2); /* まずは挿入部分 */
- #if 0
- if (!(restl = strlen(seed))) { /* 空なら終わり */
- return;
- }
- #endif
- if (up == NIL) {
- error("バグが発生しました");
- return;
- /* ctrl_x_ctrl_c();*/
- }
-
- line_make_bag_list(seed);
- /*printf("seed = %s",seed);binkey();*/
-
- while(1) {
- wp = line_get_from_bag();
- if (BAG_HEAD == NIL) { /* 最後の行なら抜ける */
- break;
- }
- line_insert1_mae_echo(wp,up); /* 1行挿入 */
- }
-
- if ((up == TAIL) && wp) {
- line_insert1_mae_echo(wp,up); /* 最後の一行を挿入して終り */
- return;
- }
-
- np = up;
- line_get_body(seed,wp); /* 最後の一行のデータを取って来る */
- while(strlen(seed)) {
- if (np == TAIL) { /* 最後に達した */
- wp = line_get_free_and_store(seed);
- line_append1_echo(wp);
- /*window0();printf("1break");binkey();*/
- break;
- }
- line_get_body(w0,np); /* w0 は常にその次の行の中身を示す */
- /*window0();printf("[%s][%s]",seed,w0);binkey();*/
- flag = cut_2line_link_check(seed,w0,retw,seed,CURRENT_JIZUME);
- if (!flag) { /* 出入りが無かった */
- line_empty_bag((STR) NIL);
- wp = line_get_free_and_store(retw);
- line_insert1_mae_echo(wp,np); /* 最後の一行を挿入して終り */
- /*window0();printf("2break");binkey();*/
- break;
- }
- if (flag < 0) { /* 前に送られた */
- if (!strlen(seed) && (etc_last(retw) != CR)) { /* 短過ぎた */
- /* もしくはちょうど */
- /*window0();printf("TOO SHORT[%s][%s]",seed,retw);binkey();*/
- strcpy(seed,retw); /* 戻す */
- /* np -> w0 ですでに追加してある! */
- np = np->ATO;
- line_delete1_echo_after_bag(np->MAE);
- if (np == TAIL) { /* もう後はないから1行作って終わり */
- /*window0();printf(seed);binkey();*/
- wp = line_get_free_and_store(seed);
- /* line_delete1_echo_after_bag(TAIL->MAE);*/
- line_append1_echo(wp);
- /*window0();printf("3break");binkey();*/
- break;
- }
- continue;
- #if 0
- line_cat_body(seed,np); /* その次の行を取って来る */
- window0();printf("TOO SHORT2[%s]",seed);binkey();
- /* strcat(seed,w0);*/
- np = np->ATO;
- line_delete1_echo_after_bag(np->MAE);
- /* 一行削除:ただしその行は袋の後ろにあること */
- continue;
- #endif
- } else { /* retw で1行作って良い */
- line_store_and_echo(np,retw);
- np = np->ATO;
- continue;
- }
- }
- if (flag > 0) { /* 後ろに送った */
- /* retw で1行作って良い */
- wp = line_get_free_and_store(retw);
- /* line_store_and_echo(np,retw);*/
- line_insert1_mae_echo(wp,np); /* 挿入する */
- np = np->ATO;
- /*window0();printf(seed);binkey();*/
- seed[strlen(seed)-strlen(w0)] = EOS;
- /* w0 は変わらず */
- continue;
- }
- }
- return;
- }
-
- /* up の指す行から、次々に整行して行く。最後まで勝負する */
- /* エコーする */
- void
- line_arrange_all(UNIT *up)
- {
- register UNIT *wp,*wp0,*wp1;
- UBYTE w0[VERY_LONG_LINE*2],w1[VERY_LONG_LINE];
-
- if ((wp0 = up) == TAIL) { /* エラーやがな */
- return;
- }
- line_get_body(w0,wp0);
- wp1 = wp0->ATO;
-
- while(1) {
- if (wp1 != TAIL) { /* 最後の行でないなら */
- line_get_body(w1,wp1); /* 行のデータを取って来る */
- strcat(w0,w1);
- wp = wp1->ATO;
- /*printf("[[%x:%x]]\n",wp1,wp);binkey();*/
- line_set_free(wp1); /* wp1 を捨てる */
- wp1 = wp;
- }
- while(1) {
- cut_line(w0,w1,w0,CURRENT_JIZUME); /* カットしてみる */
- if (*w0) { /* 1行取れた */
- wp = line_get_free_and_store(w1);
- /*printf("(取れた%d:%d)",strlen(w1),kkk);binkey();*/
- line_insert1_mae(wp,wp0);
- } else {
- /*printf("(取れなかった%d:%d)",strlen(w1),kkk);binkey();*/
- strcpy(w0,w1); /* 戻す */
- /*window0();printf("4break");binkey();*/
- break;
- }
- }
- if (wp1 == TAIL) {
- line_store(wp0,w0);
- wp0->ATO = TAIL;
- TAIL->MAE = wp0;
- /*window0();printf("5break");binkey();*/
- break;
- }
- }
- }
-
- void
- line_to_bag(STR s)
- {
- STR b;
- UBYTE bag_temp_work[VERY_LONG_LINE];
- int l;
-
- if ((BAG_LENGTH + (l = strlen(s))) > BAG_LIMIT) {
- line_arrange(SCREEN[CWY1]->ATO,s,BAG);
- line_empty_bag((STR) NIL); /* 袋を空にする */
- } else {
- strcpy(BAG0,s);
- strcat(BAG0,BAG);
- b = BAG;
- BAG = BAG0;
- BAG0 = b;
- BAG_LENGTH += l;
- }
- }
-
- void
- line_seigyou()
- {
- if (SCREEN[CWY1] && BAG_LENGTH) {
- under_print((STR) "整行中・・・");
- if (SCREEN[CWY1] == TAIL) error("6666");
- if (SCREEN[CWY1]->ATO == NIL) error("7777");
- line_arrange(SCREEN[CWY1]->ATO,(UBYTE *)"\0",BAG);/* ,,, */
- line_empty_bag((STR) NIL); /* 袋を空にする */
- under_blanc();
- }
- }
-
- /* s に袋の中身を転送し、袋を空にする */
- /* s が NIL なら転送しない */
- void
- line_empty_bag(STR s)
- {
- if (!BAG_LENGTH) { /* 袋は空である */
- if (s) {
- *s = EOS;
- }
- } else { /* 袋は空ではない */
- if (s) {
- strcpy(s,BAG);
- }
- }
- *BAG_CONTENT0 = *BAG_CONTENT1 = EOS;
- BAG = BAG_CONTENT0;
- BAG0 = BAG_CONTENT1;
-
- while(BAG_HEAD) {
- UNIT *p;
-
- p = BAG_HEAD->ATO;
- line_set_free(BAG_HEAD);
- BAG_HEAD = p;
- }
- BAG_LENGTH = 0; /* 袋の初期化 */
- BAG_HEAD = BAG_TAIL = NIL; /* bag の頭、尻尾へのポインタを無効化 */
- }
-
- /* 一行削除:ただしその行は袋の後ろにあること */
- /* エコーしない */
- void
- line_delete1(UNIT *up)
- {
- line_deleten(up->MAE,up->ATO); /* 二つの行の間を削除する */
- }
-
- /* 一行削除:ただしその行は袋の後ろにあるか、もしくは整行済みであること */
- /* エコーする */
- void
- line_delete1_echo_after_bag(UNIT *up)
- {
- line_deleten_echo(up->MAE,up->ATO); /* 二つの行の間を削除する */
- }
-
- void
- line_connect(UNIT *maep,UNIT *atop)
- {
- maep->ATO = atop; /* 前の行の後ろを、後ろの行にする */
- atop->MAE = maep; /* 後ろの行の前を、前の行にする */
- }
-
- /* maep < 削除される < atop */
- /* 与えられた行は削除されない */
- void
- line_deleten_echo(UNIT *maep,UNIT *atop)
- {
- UNIT *wp_mae,*wp_ato,*wp,*wp0;
-
- wp_mae = maep;
- wp_ato = atop;
- wp = wp_mae->ATO;
-
- /* atop を wp_mae に手繰る */
- while((wp_mae = wp) != atop) {
- if (wp_ato) { /* 尾に当たれば自動的に止まる */
- disp_replace(wp_mae,wp0 = wp_ato); /* 前を後で置き換える */
- wp = wp_mae->ATO;
- wp_ato = wp_ato->ATO;
- line_set_free_with_ext(wp_mae);
- } else {
- /* disp_replace(wp_mae,wp0 = wp_ato); 前を後で置き換える */
- break;
- }
- }
- if (wp_ato) {
- disp_replace_after(wp0,wp0->ATO);
- }
- line_connect(maep,atop); /* 二つの行を接続する */
- }
-
- #if 1
- /* SCREEN[] から maep < 削除される < atop */
- /* 与えられた行は削除されない */
- void
- line_deleten_SCREEN(UNIT *maep,UNIT *atop)
- {
- UNIT *wp_mae,*wp_ato,*wp,*wp0;
- UBYTE string[VERY_LONG_LINE];
-
- line_connect(maep,atop); /* 二つの行を接続する */
- return;
-
- wp_mae = maep;
- wp_ato = atop;
- wp = wp_mae->ATO;
-
- /* atop を wp_mae に手繰る */
- while((wp_mae = wp) != atop) { /* atop は削除されないから、そこに達したら終了 */
- if (wp_ato) { /* 尾に当たれば自動的に止まる */
- disp_replace_SCREEN(wp_mae,wp0 = wp_ato); /* 前を後で置き換える */
- wp = wp_mae->ATO;
- wp_ato = wp_ato->ATO;
- line_set_free_with_ext(wp_mae);
- } else {
- /* disp_replace_SCREEN(wp_mae,wp0 = wp_ato); 前を後で置き換える */
- break;
- }
- }
- if (wp_ato) {
- disp_replace_after_SCREEN(wp0,wp0->ATO);
- }
- /* disp_replace_after(atop->MAE,atop);*/
- /* line_set_free_with_ext(atop->MAE);*/
- line_connect(maep,atop); /* 二つの行を接続する */
- }
- #endif
-
- /* maep < 削除される < atop */
- /* 与えられた行は削除されない */
- /* エコーしない */
- void
- line_deleten(UNIT *maep,UNIT *atop)
- {
- register UNIT *wp_mae,*wp;
-
- wp_mae = maep->ATO;
- /*printf("[%x:%x]",maep,atop);binkey();*/
- do {
- wp = wp_mae->ATO;
- line_set_free_with_ext(wp_mae);
- } while((wp_mae = wp) != atop);
-
- line_connect(maep,atop); /* 二つの行を接続する */
- }
-
- /* seed をカッティングして袋のリストにする */
- void
- line_make_bag_list(STR seed)
- {
- UBYTE s[VERY_LONG_LINE],l[VERY_LONG_LINE],w[VERY_LONG_LINE];
- UNIT *p;
- UINT c,jizume;
- FILE *fp;
-
- *s = EOS; /* 前からの繰り越しはなし */
- jizume = CURRENT_JIZUME;
- do {
- if (!*s) { /* s がヌルなら適当な長さだけ読み出す */
- strncpy(s,seed,jizume + 4);
- s[jizume + 4] = EOS;
- seed += strlen(s);
- }
- while(1) {
- if (string_disp_len(s) > (jizume+4)) { /* 禁則はみだしがあるので長め */
- break;
- }
- strncpy(l,seed,jizume + 4);
- l[jizume + 4] = EOS;
- seed += strlen(l); /* 適当な長さだけ読み出す */
- strcat(s,l); /* 前からの繰り越しの後に加える */
- if (!*seed) break;
- }
- if (!*s) { /* 前部使った */
- break;
- }
- cut_line(s,w,s,jizume);
-
- p = line_append_bag_list(w);
- if (p == NIL) { /* フリーラインが無い! */
- etc_inp_y((STR)"メモリが足りません。中断します [Y]?");
- line_empty_bag(NULL);
- return;
- }
- } while(*seed || *s);
- }
-
- UNIT *
- line_append_bag_list(UBYTE *s)
- {
- UNIT *p;
-
- if (!(p = line_get_free_and_store(s))) return(NIL);
-
- if (BAG_HEAD) { /* 袋リストがある */
- BAG_TAIL->ATO = p; /* 最後の次が手持ちになる */
- p->MAE = BAG_TAIL; /* 手持ちの前は最後 */
- p->ATO = NIL; /* 新しい最後は NIL を指す */
- BAG_TAIL = p; /* 新しい最後を指す */
- } else { /* フリーラインがない */
- BAG_HEAD = BAG_TAIL = p;
- p->MAE = p->ATO = NIL;
- }
- return(p);
- }
-
- /* 袋リストの頭から順番に1つづつ外して行く */
- UNIT *
- line_get_from_bag()
- {
- UNIT *wp;
-
- if (wp = BAG_HEAD) {
- BAG_HEAD = BAG_HEAD->ATO;
- } /* HEAD が NIL なら TAIL は無効だからこれでいいのだ */
- return(wp);
- }
-
- /* 文字列にユニットの中身を追加する */
- /* 追加した長さを返す */
- int
- line_cat_body(STR l,UNIT *p)
- {
- register int i;
-
- strcat(l,p->BODY);
- i = line_length(p);
- while (p = p->EXT) {
- strcat(l,p->BODY);
- }
- return(i);
- }
-
-
- /* テキストの末尾に1行アペンドする */
- /* エコーしない */
- void
- line_append1(UNIT *unit_pointer)
- {
- line_insert1_mae(unit_pointer,TAIL);
- }
-
- /* テキストの末尾に1行アペンドする */
- /* エコーする */
- void
- line_append1_echo(UNIT *unit_pointer)
- {
- line_insert1_mae_echo(unit_pointer,TAIL);
- }
-
- /* text_line_pointer の後ろに1行挿入する */
- /* エコーする */
- void
- line_insert1_after(UNIT *insert_unit_pointer,UNIT *text_line_pointer)
- {
- UNIT *n;
-
- if (text_line_pointer == TAIL) {
- error("バグです。TAIL の後ろに挿入しようとした");
- } else {
- line_insert1_mae_echo(insert_unit_pointer,text_line_pointer->ATO);
- }
- }
-
- /* text_line_pointer の前に1行挿入する */
- /* エコーする */
- void
- line_insert1_mae_echo(UNIT *insert_unit_pointer,UNIT *text_line_pointer)/* ,,,, */
- {
- UNIT *b;
-
- line_insert1_mae(insert_unit_pointer,text_line_pointer);
- disp_check_1line_insert(insert_unit_pointer,text_line_pointer);
- /* 必要ならば画面にエコーする */
- }
-
- /* text_line_pointer の前に1行挿入する */
- /* エコーしない */
- void
- line_insert1_mae(UNIT *insert_unit_pointer,UNIT *text_line_pointer)
- {
- UNIT *b;
-
- if (!insert_unit_pointer) { /* メモリの限界に来ている */
- etc_beep();
- under_print0((STR)"メモリ不足:文章を保存して、終了して下さい [Y]? ");
- etc_wait_y();
- insert_unit_pointer = &AXE;
- }
-
- if (text_line_pointer == HEAD) {
- error("バグです。HEAD の前に挿入しようとした");
- } else {
- b = text_line_pointer->MAE; /* 前の行へのポインタ */
- text_line_pointer->MAE = b->ATO = insert_unit_pointer;
- insert_unit_pointer->ATO = text_line_pointer;
- /* 後ろのリンク */
- insert_unit_pointer->MAE = b; /* 前のリンク */
- }
- }
-
-
- /* フリーラインを新しく得て、与えられた文字列を格納する */
- /* 1ユニットで格納しきれない時は自動的に拡張する */
- UNIT *
- line_get_free_and_store_with_echo(STR s)
- {
- UNIT *p,*p0,*q;
- int l,lmin;
-
- if (p = line_get_free()) {
- if (line_store_and_echo(p,s)) {
- return(p);
- } else {
- line_set_free(p);
- }
- }
- return(NIL); /* 得られなかった */
- }
-
- /* フリーラインを新しく得て、与えられた文字列を格納する */
- /* 1ユニットで格納しきれない時は自動的に拡張する */
- UNIT *
- line_get_free_and_store(STR s)
- {
- UNIT *p,*p0,*q;
- int l,lmin;
-
- if (p = line_get_free()) {
- if (line_store(p,s)) {
- return(p);
- } else {
- line_set_free(p);
- }
- } else {
- return(NIL); /* 1行も得られなかった */
- }
- }
-
- UNIT *
- line_get_free_and_store_ck(STR s)
- {
- register UNIT *p;
-
- if (!(p = line_get_free_and_store(s))) {
- error("おそらくメモリ不足です。新しい行を確保出来ません");
- }
- return(p);
- }
-
- /* 指定されたユニット(拡張可)に与えられた文字列を格納する */
- /* 格納しきれない時は自動的に拡張する、余った場合も自動的に開放する */
- /* 画面にエコーする */
- UNIT *
- line_store_and_echo(UNIT *up, STR s)
- {
- UNIT *wp;
-
- if (up == TAIL) {
- wp = line_get_free_and_store(s);
- line_append1_echo(wp);
- } else {
- line_store(up,s);
- disp_check_1line_echo(up);
- }
- }
-
-
- /* 指定されたユニット(拡張可)に与えられた文字列を格納する */
- /* 格納しきれない時は自動的に拡張する、余った場合も自動的に開放する */
- /* エコーしない */
- UNIT *
- line_store(UNIT *up, STR s)
- {
- UNIT *p,*q;
- int l,lmin;
-
- up->LENGTH = l = strlen(s);
- if (l < BODYSIZE-1) {
- strcpy(up->BODY,s);
- if (up->EXT) {
- line_set_free_with_ext(up->EXT);
- up->EXT = NIL;
- }
- return(up);
- }
-
- strncpy(up->BODY,s,lmin = BODYSIZE-1); /* 最初のユニット */
- s += lmin;
- p = up;
-
- while ((l -= lmin) > 0) { /* long line */
- p->BODY[BODYSIZE-1] = EOS; /* EOS を追加 */
- if (!(q = p->EXT)) { /* 拡張が必要なのに今は持ってない */
- if (q = line_get_free()) { /* 取れた */
- p->EXT = q;
- } else { /* 取れなかった */
- line_set_free_with_ext(up->EXT);
- return(NIL);
- }
- }
- lmin = min(BODYSIZE-1,l);
- strncpy(q->BODY,s,lmin);
- (q->BODY)[lmin] = EOS;
- s += lmin;
- p = q;
- }
- if (p->EXT) {
- line_set_free_with_ext(p->EXT);
- p->EXT = NIL;
- }
- return(up);
- }
-
- void
- line_get_body(STR s,UNIT *p)
- {
- if (p) {
- strcpy(s,p->BODY);
- while (p = p->EXT) {
- strcat(s,p->BODY);
- }
- }
- }
-
- /* エラーなら 0 を返す */
- int
- line_make_line(int number_of_line)
- {
- int i;
- UNIT *ptr;
-
- if (number_of_line) {
- if (ptr = line_get_memory(number_of_line)) {
- /* フリーラインに追加していく */
- for(i = 0;i < number_of_line;i++) {
- line_set_free(ptr++);
- }
- } else {
- return(FALSE); /* 必要な領域を確保できなかった */
- }
- }
- return(TRUE);
- }
-
- /* メモリの確保 */
- UNIT *
- line_get_memory(int number_of_line)
- {
- int s;
-
- s = number_of_line*sizeof(UNIT);
- if (s % 1024) {
- s = s/1024+1;
- } else {
- s = s/1024;
- }
- bldmem(s);
- return((UNIT *)calloc(number_of_line,sizeof(UNIT)));
- /* calloc は0で初期化する */
- }
-
- /* フリーなユニットへのポインタを返す */
- /* フリーリストから外す */
- /* 頭から外していく */
- /* ない場合は NIL を返す */
- UNIT *
- line_get_free()
- {
- UNIT *p;
-
- /*
- if (sysflag) {
- int *BUS = 0;
-
- error("###");
- *BUS = 0;
- return;
- }
- sysflag = 1;
- */
- if (LINE_SHORT) {
- return(&AXE);
- }
- /* フリーラインがない */ /* 作れない */
- if ((!FREE_LINE_COUNTER) && (!line_make_line(128))) {
- LINE_SHORT = 1;
- under_print0((STR)"重大な事態。メモリ不足:大事な文章を保存して、終了して下さい [Y]? ");
- etc_wait_y();
- return(&AXE);
- /* return(NIL);*/
- }
-
- FREE_LINE_COUNTER--; /* フリーラインがある */
- p = FREE_HEAD;
- if (FREE_HEAD = FREE_HEAD->ATO) { /* 次がある(最後ではなかった) */
- FREE_HEAD->MAE = NIL; /* 新しい先頭行の前は NIL */
- } else { /* 最後の行だった */
- FREE_TAIL = NIL; /* 尻尾に NIL を指させる */
- }
-
- p->MAE = NIL;
- p->ATO = NIL;
- p->EXT = NIL;
- p->LENGTH = 0;
- p->BODY[0] = EOS;
- return(p);
- }
-
- /* フリーなユニットにする */
- void
- line_set_free(UNIT *unit_pointer)
- {
- if (FREE_LINE_COUNTER) { /* フリーラインがある */
- FREE_TAIL->ATO = unit_pointer; /* 最後の次が手持ち */
- unit_pointer->MAE = FREE_TAIL; /* 手持ちの前は最後 */
- unit_pointer->ATO = NIL; /* 新しい最後は NIL を指す */
- unit_pointer->EXT = NIL;
- FREE_TAIL = unit_pointer; /* 新しい最後を指す */
- } else { /* フリーラインがない */
- FREE_HEAD = FREE_TAIL = unit_pointer;
- unit_pointer->MAE = unit_pointer->ATO = NIL;
- }
-
- FREE_LINE_COUNTER++;
- }
-
- /* 拡張を含めて開放する */
- /* 再帰を使ってランララン */
- void
- line_set_free_with_ext(UNIT *unit_pointer)
- {
- UNIT *xp;
-
- if (xp = unit_pointer->EXT) {
- line_set_free_with_ext(xp);
- }
- line_set_free(unit_pointer);
- }
-
- /* 現在行の n 文字目の文字コードを1バイト取って来る */
- UBYTE
- line_cl_1byte(int n)
- {
- return(*(line_skip_xcode(CL_DATA + ANALYZE[n].BPOS)));
- }
-
- /* 現在行の n 文字目の文字コードを1文字取って来る */
- UINT c;
- line_cl_code(int n)
- {
- register STR p;
- register UINT c;
-
- p = line_skip_xcode(CL_DATA + ANALYZE[n].BPOS);
- if (iskanji(c = *p++)) {
- c = (c<<8) | *p;
- }
- return(c);
- }
-
- /* カーソルの下の文字コードを1バイト取って来る */
- UBYTE
- line_cpx_1byte()
- {
- return(*(line_skip_xcode(CL_DATA + ANALYZE[CPX].BPOS)));
- }
-
- /* カーソルの下の文字コードを取って来る */
- UINT
- line_cpx_code()
- {
- register STR wp;
- UINT c;
-
- wp = line_skip_xcode(&CL_DATA[ANALYZE[CPX].BPOS]); /* 実体のアドレスを得る */
- if (etc_char_byte_haba(wp) <= 1) {
- return(*wp);
- } else {
- c = *wp++;
- return(c << 8 | *wp);
- }
- }
-
- /* 拡張コードをスキップする */
- /* ポインタを返す */
- STR
- line_skip_xcode(STR p)
- {
- register UINT c1;
-
- while(*p == XCODE_UP) {
- c1 = *++p;
- p++;
- /* c1 を見て、ルビならさらに進める */
- if ((XCODE_RB10 <= c1) && (c1 <= XCODE_RB2)) { /* ルビだ */
- p += 2;
- if (c1 == XCODE_RB2) {
- p += 2;
- }
- }
- }
- return(p);
- }
-
- /* マークコードをスキップする */
- /* ポインタを返す */
- STR
- line_skip_mark(STR p)
- {
- register UINT c1;
-
- while(*p == XCODE_UP) {
- if ((XCODE_SYSMARK <= p[1]) && (p[1] <= XCODE_MARKLAST)) { /* マークだ */
- p += 2;
- } else {
- return(p);
- }
- }
- }
-
- #if 0
- /* 文字列の最初の1文字が占めるバイト数を返す(拡張コードも含めたバイト数) */
- UINT
- line_cxp_char_byte(STR p)
- {
- register int i = 0;
-
- while(p[i] == XCODE_UP) {
- i += 2;
- }
- return(i + etc_char_byte_haba(p));
- }
- #endif
-
- /* CL_DATA[bc] から始めて、次の文字までのバイト数を返す */
- /* *xc から表示しているとして、*xc を更新する */
- int
- line_touch_next_char(int bc,int *xc)
- {
- return(line_touch_next_char_x(CL_DATA,bc,xc));
- }
-
- /* p[bc] から始めて、次の文字までのバイト数を返す */
- /* *xc から表示しているとして、*xc を更新する */
- /* 実体を越える */
- int
- line_touch_next_char_x(STR p,int bc,int *xc)
- {
- register UBYTE c;
- register UWORD w;
-
- if ((c = p[bc]) < (UBYTE)'\x20') {
- switch(c) {
- case EOS:
- return(bc);
- case TAB: /* TAB 0-7 -> 8, 8-15 -> 16... */
- w = *xc + TAB_LENGTH;
- w -= (w % TAB_LENGTH);
- *xc = min(w,CURRENT_JIZUME);
- /* *xc = w - (w % TAB_LENGTH);*/
- return(bc + 1);
- case CR: /* 改行 */
- (*xc) += 2;
- return(bc + 1);
-
- default: /* 普通のコントロールコード */
- (*xc) += 2;
- return(bc + 1);
- }
- }
- if (c == XCODE_UP) { /* 拡張コード */
- switch(p[bc+1]) { /* 次の1バイトが */
- case XCODE_MARK+0:
- case XCODE_MARK+1:
- case XCODE_MARK+2:
- case XCODE_MARK+3:
- case XCODE_MARK+4:
- case XCODE_MARK+5:
- case XCODE_MARK+6:
- case XCODE_MARK+7:
- case XCODE_MARK+8:
- case XCODE_MARK+9: /* マーク 0x20 - 0x29 */
- case XCODE_MARK+10:
- case XCODE_MARK+11:
- case XCODE_MARK+12:
- case XCODE_MARK+13:
- case XCODE_MARK+14:
- case XCODE_MARK+15:
-
- case XCODE_SYSMARK+0: /* システムマーク */
- case XCODE_SYSMARK+1:
- case XCODE_SYSMARK+2:
- case XCODE_SYSMARK+3:
- case XCODE_SYSMARK+4:
- case XCODE_SYSMARK+5:
- case XCODE_SYSMARK+6:
- case XCODE_SYSMARK+7:
- case XCODE_SYSMARK+8:
- case XCODE_SYSMARK+9:
- case XCODE_SYSMARK+10:
- case XCODE_SYSMARK+11:
- case XCODE_SYSMARK+12:
- case XCODE_SYSMARK+13:
- case XCODE_SYSMARK+14:
- case XCODE_SYSMARK+15:
- case XCODE_UL: /* 下線 */
- return(line_touch_next_char_x(p,bc+2,xc));
-
- case XCODE_RB10: /* 予約:1文字真ん中ルビ */
- case XCODE_RB1: /* 1文字ルビ */
- case XCODE_RB1L: /* 1文字ルビ左(全角用) */
- case XCODE_RB1R: /* 1文字ルビ右(全角用) */
- return(line_touch_next_char_x(p,bc+4,xc));
-
- case XCODE_RB2: /* 2文字ルビ */
- return(line_touch_next_char_x(p,bc+6,xc));
- }
- }
- if (iskanji(c)) { /* 普通の全角 */
- (*xc) += 2;
- return(bc + 2);
- }
- if (buff_ishan2byte(c)) {
- (*xc)++;
- return(bc + 2);
- }
- (*xc)++;
- return(bc + 1);
- }
-
- /* */
- /* void */
- line_cl_cl()
- {
- register UNIT *p = CL;
-
- if (p) {
- strcpy(CL_DATA,p->BODY);
- while (p = p->EXT) {
- strcat(CL_DATA,p->BODY);
- }
- }
- }
-
- /* s に CL_DATA から n バイトコピーする */
- void
- line_cl_strncpy(STR s,int n)
- {
- strncpy(s,CL_DATA,n);
- }
-
- /* s に CL_DATA の n バイト目からのデータを追加する */
- void
- line_cl_strcat(STR s,int n)
- {
- strcat(s,&CL_DATA[n]);
- }
-
- /* s に CL_DATA の n バイト目からの l バイトのデータを追加する */
- void
- line_cl_strncat(STR s,int n,int l)
- {
- strncat(s,&CL_DATA[n],l);
- }
-
- /* maep <= 削除される <= atop */
- /* 与えられた行は削除されない */
- /* エコーしない */
- void
- line_deleten_list(UNIT *maep,UNIT *atop)
- {
- register UNIT *wp;
-
- /*window0();*/
- if (maep) {
- while(1) {
- wp = maep->ATO;
- /*printf("[%x]\n",maep);binkey();*/
- line_set_free_with_ext(maep);
- if (maep == atop) {
- break;
- }
- maep = wp;
- }
- }
- }
-
- int
- line_length(UNIT *p)
- {
- return(p->LENGTH);
- }
-
- /* CL_DATA の前置している属性までさかのぼる */
- /* 解析済み */
- int
- line_remove_attribute(int bp1)
- {
- register int i,j;
-
- j = i = 0;
- while(bp1 >= ANALYZE[i].BPOS) {
- j = i++;
- }
- if (bp1 == ANALYZE[i].BPOS) {
- return(bp1);
- } else {
- return(ANALYZE[j].BPOS);
- }
- }
-
-